{
 "cells": [
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T12:52:23.836426Z",
     "start_time": "2025-05-24T12:52:23.832949Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ==================== 1. 依赖库导入 ====================\n",
    "import os\n",
    "import re\n",
    "import nltk\n",
    "from nltk.corpus import stopwords\n",
    "from nltk.stem import WordNetLemmatizer\n",
    "from nltk.tokenize import word_tokenize\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.linear_model import Perceptron, LogisticRegression\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "from sklearn.metrics import accuracy_score, classification_report\n"
   ],
   "id": "a7ea5d3e50b1b04b",
   "outputs": [],
   "execution_count": 11
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T12:52:29.197785Z",
     "start_time": "2025-05-24T12:52:29.190022Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ==================== 2. 数据预处理 ====================\n",
    "nltk.download('stopwords')\n",
    "nltk.download('wordnet')\n",
    "nltk.download('punkt')\n",
    "\n",
    "def preprocess_text(text):\n",
    "    # 清洗特殊字符\n",
    "    text = re.sub(r'[^a-zA-Z\\s]', '', text)\n",
    "    # 文本标准化\n",
    "    text = text.lower()\n",
    "    words = word_tokenize(text)\n",
    "    # 停用词过滤\n",
    "    stop_words = set(stopwords.words('english'))\n",
    "    words = [word for word in words if word not in stop_words]\n",
    "    # 词形还原\n",
    "    lemmatizer = WordNetLemmatizer()\n",
    "    words = [lemmatizer.lemmatize(word) for word in words]\n",
    "    # 过滤短词\n",
    "    return \" \".join([word for word in words if len(word) > 2])\n"
   ],
   "id": "a08470172a5c2d2c",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[nltk_data] Downloading package stopwords to\n",
      "[nltk_data]     C:\\Users\\15038\\AppData\\Roaming\\nltk_data...\n",
      "[nltk_data]   Package stopwords is already up-to-date!\n",
      "[nltk_data] Downloading package wordnet to\n",
      "[nltk_data]     C:\\Users\\15038\\AppData\\Roaming\\nltk_data...\n",
      "[nltk_data]   Package wordnet is already up-to-date!\n",
      "[nltk_data] Downloading package punkt to\n",
      "[nltk_data]     C:\\Users\\15038\\AppData\\Roaming\\nltk_data...\n",
      "[nltk_data]   Package punkt is already up-to-date!\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T12:52:32.234548Z",
     "start_time": "2025-05-24T12:52:32.229785Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ==================== 3. 数据加载 ====================\n",
    "def load_data(data_path):\n",
    "    texts = []\n",
    "    labels = []\n",
    "    for label in ['pos', 'neg']:\n",
    "        for split in ['train', 'test']:\n",
    "            path = os.path.join(data_path, split, label)\n",
    "            for file_name in os.listdir(path):\n",
    "                if file_name.endswith('.txt'):\n",
    "                    with open(os.path.join(path, file_name), 'r', encoding='utf-8') as file:\n",
    "                        texts.append(preprocess_text(file.read()))\n",
    "                        labels.append(1 if label == 'pos' else 0)\n",
    "    return texts, labels"
   ],
   "id": "7f597ad42b18b4ff",
   "outputs": [],
   "execution_count": 14
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T12:53:31.575038Z",
     "start_time": "2025-05-24T12:52:34.529532Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ==================== 4. 数据集划分 ====================\n",
    "data_path = 'D:/mytest/chenyajie/Moive/aclImdb'\n",
    "texts, labels = load_data(data_path)\n",
    "X_train, X_test, y_train, y_test = train_test_split(texts, labels, test_size=0.2, random_state=42)\n"
   ],
   "id": "20ec5b8895f17ff8",
   "outputs": [],
   "execution_count": 15
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T12:53:39.538432Z",
     "start_time": "2025-05-24T12:53:35.387092Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ==================== 5. 特征工程 ====================\n",
    "vectorizer = TfidfVectorizer()\n",
    "X_train_vec = vectorizer.fit_transform(X_train)\n",
    "X_test_vec = vectorizer.transform(X_test)"
   ],
   "id": "a7ba5cdac40cab6f",
   "outputs": [],
   "execution_count": 16
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-23T14:32:54.188634Z",
     "start_time": "2025-05-23T14:19:51.957894Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# -------------------- 6.6 K近邻模型 --------------------\n",
    "import time\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.metrics import classification_report\n",
    "\n",
    "# 定义K近邻模型的参数网格\n",
    "knn_param_grid = {\n",
    "    'n_neighbors': [3, 5, 7, 9],\n",
    "    'weights': ['uniform', 'distance'],\n",
    "    'algorithm': ['brute']  # 显式指定使用brute算法\n",
    "}\n",
    "\n",
    "# 创建K近邻模型\n",
    "knn = KNeighborsClassifier()\n",
    "\n",
    "# 创建网格搜索对象\n",
    "knn_grid_search = GridSearchCV(knn, knn_param_grid, cv=3)\n",
    "\n",
    "# 记录开始时间\n",
    "start_time = time.time()\n",
    "\n",
    "# 模型训练\n",
    "knn_grid_search.fit(X_train_vec, y_train)\n",
    "\n",
    "# 记录结束时间\n",
    "end_time = time.time()\n",
    "\n",
    "# 获取最佳模型\n",
    "best_knn = knn_grid_search.best_estimator_\n",
    "\n",
    "# 预测\n",
    "y_pred_knn = best_knn.predict(X_test_vec)\n",
    "\n",
    "# 输出分类报告，并格式化小数点四位\n",
    "print(\"K-Nearest Neighbors Classification Report:\")\n",
    "report = classification_report(y_test, y_pred_knn, digits=4)\n",
    "print(report)\n",
    "\n",
    "# 计算训练时间\n",
    "training_time = end_time - start_time\n",
    "print(f\"Training Time: {training_time:.4f} seconds\")\n",
    "\n",
    "# 输出最佳参数\n",
    "print(f\"Best Parameters: {knn_grid_search.best_params_}\")"
   ],
   "id": "7642f8b5a648c9d6",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-Nearest Neighbors Classification Report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0     0.8289    0.7121    0.7661      4978\n",
      "           1     0.7496    0.8542    0.7985      5022\n",
      "\n",
      "    accuracy                         0.7835     10000\n",
      "   macro avg     0.7892    0.7832    0.7823     10000\n",
      "weighted avg     0.7891    0.7835    0.7824     10000\n",
      "\n",
      "Training Time: 741.1995 seconds\n",
      "Best Parameters: {'algorithm': 'brute', 'n_neighbors': 9, 'weights': 'distance'}\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T13:11:52.134226Z",
     "start_time": "2025-05-24T12:53:43.443794Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# -------------------- 6.3 优化后的SVM模型 --------------------\n",
    "import time\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.feature_selection import SelectKBest, chi2\n",
    "\n",
    "# 定义SVM模型的参数网格\n",
    "svm_param_grid = {\n",
    "    'C': [0.1, 1],\n",
    "    'kernel': ['linear'],  # 使用线性核\n",
    "    'gamma': ['scale']\n",
    "}\n",
    "\n",
    "# 创建SVM模型\n",
    "svm = SVC()\n",
    "\n",
    "# 创建网格搜索对象\n",
    "svm_grid_search = GridSearchCV(svm, svm_param_grid, cv=3)\n",
    "\n",
    "# 记录开始时间\n",
    "start_time = time.time()\n",
    "\n",
    "# 特征选择：选择最重要的1000个特征\n",
    "selector = SelectKBest(chi2, k=1000)\n",
    "X_train_vec_reduced = selector.fit_transform(X_train_vec, y_train)\n",
    "X_test_vec_reduced = selector.transform(X_test_vec)\n",
    "\n",
    "# 模型训练\n",
    "svm_grid_search.fit(X_train_vec_reduced, y_train)\n",
    "\n",
    "# 记录结束时间\n",
    "end_time = time.time()\n",
    "\n",
    "# 获取最佳模型\n",
    "best_svm = svm_grid_search.best_estimator_\n",
    "\n",
    "# 预测\n",
    "y_pred_svm = best_svm.predict(X_test_vec_reduced)\n",
    "\n",
    "# 输出分类报告，并格式化小数点四位\n",
    "print(\"SVM Classification Report:\")\n",
    "report = classification_report(y_test, y_pred_svm, digits=4)\n",
    "print(report)\n",
    "\n",
    "# 计算训练时间\n",
    "training_time = end_time - start_time\n",
    "print(f\"Training Time: {training_time:.4f} seconds\")\n",
    "\n",
    "# 输出最佳参数\n",
    "print(f\"Best Parameters: {svm_grid_search.best_params_}\")"
   ],
   "id": "8ef93b0f8d8029eb",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SVM Classification Report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0     0.8943    0.8648    0.8793      4978\n",
      "           1     0.8702    0.8986    0.8842      5022\n",
      "\n",
      "    accuracy                         0.8818     10000\n",
      "   macro avg     0.8822    0.8817    0.8817     10000\n",
      "weighted avg     0.8822    0.8818    0.8818     10000\n",
      "\n",
      "Training Time: 1056.0298 seconds\n",
      "Best Parameters: {'C': 1, 'gamma': 'scale', 'kernel': 'linear'}\n"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-24T13:15:24.119430Z",
     "start_time": "2025-05-24T13:13:58.673230Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ==================== 6.5 决策树模型优化 ====================\n",
    "import time\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.model_selection import RandomizedSearchCV\n",
    "from sklearn.metrics import classification_report\n",
    "\n",
    "# 定义决策树模型的参数网格\n",
    "dt_param_grid = {\n",
    "    'criterion': ['gini', 'entropy'],\n",
    "    'max_depth': [None, 10, 30],\n",
    "    'min_samples_split': [2, 10],\n",
    "    'min_samples_leaf': [1, 4]\n",
    "}\n",
    "\n",
    "# 创建决策树模型\n",
    "dt = DecisionTreeClassifier(random_state=42)\n",
    "\n",
    "# 创建随机搜索对象，设置 n_iter=10，cv=2，并行化计算\n",
    "dt_random_search = RandomizedSearchCV(dt, dt_param_grid, n_iter=10, cv=2, n_jobs=-1, random_state=42)\n",
    "\n",
    "# 记录开始时间\n",
    "start_time = time.time()\n",
    "\n",
    "# 模型训练\n",
    "dt_random_search.fit(X_train_vec, y_train)\n",
    "\n",
    "# 记录结束时间\n",
    "end_time = time.time()\n",
    "\n",
    "# 获取最佳模型\n",
    "best_dt = dt_random_search.best_estimator_\n",
    "\n",
    "# 预测\n",
    "y_pred_dt = best_dt.predict(X_test_vec)\n",
    "\n",
    "# 输出分类报告，并格式化小数点四位\n",
    "print(\"Decision Tree Classification Report:\")\n",
    "report = classification_report(y_test, y_pred_dt, digits=4)\n",
    "print(report)\n",
    "\n",
    "# 计算训练时间\n",
    "training_time = end_time - start_time\n",
    "print(f\"Training Time: {training_time:.4f} seconds\")\n",
    "\n",
    "# 输出最佳参数\n",
    "print(f\"Best Parameters: {dt_random_search.best_params_}\")"
   ],
   "id": "4652d7a4ae9a4305",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Decision Tree Classification Report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0     0.7632    0.6902    0.7249      4978\n",
      "           1     0.7195    0.7877    0.7521      5022\n",
      "\n",
      "    accuracy                         0.7392     10000\n",
      "   macro avg     0.7414    0.7390    0.7385     10000\n",
      "weighted avg     0.7413    0.7392    0.7386     10000\n",
      "\n",
      "Training Time: 85.3848 seconds\n",
      "Best Parameters: {'min_samples_split': 10, 'min_samples_leaf': 4, 'max_depth': 30, 'criterion': 'gini'}\n"
     ]
    }
   ],
   "execution_count": 18
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
